package indi.gtl.superbrain.tools;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.Timer;

/**
 * Created by admin1 on 15-5-27.
 * 此类采用单例模式,每个应用只有一个连接
 * 一般由 @NetToolService 或 @NetToolClient 类生成
 */

public class NetTool {
    private static final String TAG = "NetTool";
    // 连接端口号
    public static final int SERVERPORT = 8888;

    public static final String CONNECTION_MSG_END = "\r\n";
    public static final String CONNECTION_MSG_SEPARATOR = "##";

    public static final int HANDLER_MSG_HAVE_MSG = 0x11;
    public static final int HANDLER_MSG_DISCONNECT = 0x22;

    private String mClientIP;
    private Socket mClientSocket;

    private BufferedReader bufferedReader = null;
    private OutputStream outputStream = null;

    public Handler inputHandler = null;
    private Handler sendHandler;

    private Thread receiveThread;
    private Thread sendThread;

    private OnReceiveMessageListener mOnReceiveMessageListener;

    private static NetTool mNetTool;

    /* 创建单例
     * 如果已存在则先断开之前的连接
     *
     */
    public static NetTool createNetTool(String ip, Socket socket){
        if(mNetTool != null){
            mNetTool.destroyConnection();
        }
        mNetTool = new NetTool(ip, socket);
        return mNetTool;
    }

    // 获取NetTool单例
    public static NetTool getNetTool(){
        return mNetTool;
    }

    //@return 返回对方ip
    public String getTheOtherIP(){
        return mClientIP;
    }

    // 设定监听接口
    public void setOnReceiveMessageListener(OnReceiveMessageListener onReceiveMessageListener){
        mOnReceiveMessageListener = onReceiveMessageListener;
    }

    /* 监听接口
     * 在收到消息时调用
     */
    public interface OnReceiveMessageListener{
        void receiveMessage(String msg);
        void onDisconnect();
    }

    // 构造方法
    private NetTool(String ip, Socket socket){
        mClientIP = ip;
        mClientSocket = socket;

        inputHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                Log.d(TAG, "接收到消息");
                switch (msg.what) {
                    case HANDLER_MSG_HAVE_MSG:
                        if(mOnReceiveMessageListener != null)
                            mOnReceiveMessageListener.receiveMessage((String) msg.obj);
                        break;
                    case HANDLER_MSG_DISCONNECT:
                        if(mOnReceiveMessageListener != null)
                            mOnReceiveMessageListener.onDisconnect();
                        break;
                }
            }
        };

        try {
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            outputStream = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        receiveThread = new Thread(){
            @Override
            public void run() {
                receiveMessage();
            }
        };
        receiveThread.setDaemon(true);
        receiveThread.start();

        sendThread = new Thread(){
            @Override
            public void run() {
                Looper.prepare();
                sendHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        Log.d(TAG, "发送了消息null");

                        if(outputStream != null){
                            try {
                                Log.d(TAG, "发送了消息");
                                outputStream.write((msg.obj + CONNECTION_MSG_END).getBytes("utf-8"));
                            } catch (IOException e) {
                                e.printStackTrace();
                                if(NetTool.getNetTool() != null) {
                                    NetTool.getNetTool().destroyConnection();
                                    Message.obtain(inputHandler, HANDLER_MSG_DISCONNECT).sendToTarget();
                                }
                            }
                        }
                    }
                };
                Looper.loop();
            }
        };
        sendThread.start();
    }

    private void receiveMessage(){
        String content = null;
        try {
            Log.d(TAG, "开始接收消息");
            while ((content = bufferedReader.readLine()) != null){
                Log.d(TAG, "接收了消息");
                while(mOnReceiveMessageListener == null){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Message.obtain(inputHandler, HANDLER_MSG_HAVE_MSG, content).sendToTarget();
            }
        } catch (IOException e) {
            e.printStackTrace();
            if(NetTool.getNetTool() != null) {
                NetTool.getNetTool().destroyConnection();
                Message.obtain(inputHandler, HANDLER_MSG_HAVE_MSG).sendToTarget();
            }
        }
    }

    // 发送消息
    public void sendMessage(String msg){
        Log.d(TAG, "向handler发送了消息" + msg);
        while(sendHandler == null){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Message.obtain(sendHandler, 1, msg).sendToTarget();
    }

    // 断开连接
    public void destroyConnection(){
        try {
            // bufferedReader.close();
            //outputStream.close();
            mClientSocket.close();
//            mNetTool.bufferedReader = null;
//            mNetTool.outputStream = null;
//            mNetTool.mClientSocket = null;
            mNetTool = null;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }
}
